package org.spbsu.apco.common.task.impl;

import org.spbsu.apco.common.data.core.DurationEstimable;
import org.spbsu.apco.common.data.impl.PrimeInputVal;
import org.spbsu.apco.common.data.impl.PrimeOutputVal;
import org.spbsu.apco.common.task.core.BaseTask;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * User: solozobov
 * Date: 25.11.12
 */

public class PrimeFindTask extends BaseTask<PrimeInputVal, PrimeOutputVal> implements DurationEstimable<PrimeInputVal> {
    @Override
    public PrimeOutputVal execute(final List<PrimeInputVal> inputData) throws Exception {
        final PrimeInputVal input = inputData.get(0);
        final ArrayList<BigInteger> primeArray = new ArrayList<BigInteger>(input.getN());

        final Random rnd = new Random();
        for (int i = 0; i < input.getN(); i++) {
            primeArray.add(new BigInteger(input.getD(), input.getP(), rnd));
        }

        final PrimeOutputVal outVal = new PrimeOutputVal();
        outVal.setAr(primeArray);
        return outVal;
    }

    @Override
    public int estimateDuration(List<PrimeInputVal> inputData) {
        PrimeInputVal inValuePrime = inputData.get(0);
        int n = inValuePrime.getN();
        int p = inValuePrime.getP();
        int d = inValuePrime.getD();

        // use Miller-Rabin algorithm running time: O(p*log(d)^3)
        return (int) Math.ceil(n * p * Math.pow(Math.log(d), 3));
    }
}
